﻿// ----------------------------------------------------------------------------------------
// Author:                    Magaly Vargas y Joaquín López
// Company:                   ALBALIA INTERACTIVA S.L.
// Assembly version:          1.0.0.0
// Date:                      22/02/2010
// Time:                      12:00
// Solution Name:             OffInvoiceWordAddIn
// Solution Filename:         OffInvoiceWordAddIn
// Solution FullFilename:     C:\Desarrollo\OffInvoiceWordAddIn
// Project Name:              OffInvoiceWordAddIn
// Project Filename:          OffInvoiceWordAddIn.csproj
// Project FullFilename:      C:\Desarrollo\OffInvoiceWordAddIn\OffInvoiceWordAddIn.csproj
// Project Item Name:         UBLGenerator.cs
// Project Item Filename:     UBLGenerator.cs
// Project Item FullFilename: C:\Desarrollo\OffInvoiceWordAddIn\UBLFiles\UBLGenerator.cs
// Project Item Kind:         Código
// Purpose:                   
//Copyright © 2009 - 2010 Albalia Interactiva S.L. Reservados todos los derechos.
// ----------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.ComponentModel;
using System.Xml.Serialization;
using System.Globalization;
using OffInvoiceWordAddIn;
using OffInvoiceWordAddIn.UBLFiles;
using Microsoft.Office.Interop.Word;

namespace OffInvoiceWordAddIn.UBLFiles
{

    /// <summary>
    /// Clase encargada de formar la factura UBL de acuerdo con los datos insertados en la plantilla
    /// Completa la informacion y realiza los calculos y operaciones necesarias para formar la factura UBL
    /// </summary>
    /// <remarks>
    /// Algunos datos son opcionales por lo que dependen de ciertos valores que aparezcan en el xml.
    /// Los campos nulos no aprecen en el documento
    /// </remarks>
    class UBLGenerator
    {
        #region "Fields"

        /// <summary>
        /// Referencia al documento activo
        /// </summary>
        Document document = null;

        /// <summary>
        /// Numeración de las tablas del documento
        /// </summary>
        int t2, t3, t4, t5, t6, t7;

        /// <summary>
        /// Array de caracteres para eliminar en la captura de datos
        /// </summary>
        char[] x = { '\r', '\a', '\n' };

        /// <summary>
        /// Campo de tipo double que almacena el importe bruto
        /// </summary>
        double totalGrossAmount = 0;

        /// <summary>
        /// Campo de tipo double que almacena el importe de los impuestos repercutidos
        /// </summary>
        double totalTaxOutputs = 0;

        /// <summary>
        /// Campo de tipo double que almacena el importe de los impuestos retenidos
        /// </summary>
        double totalIRPF = 0;

        /// <summary>
        /// Campo de tipo double que almacena el importe bruto antes de impuestos
        /// </summary>
        double totalGrossAmountBeforeTaxes = 0;

        /// <summary>
        /// Campo de tipo double que almacena el importe total de los descuentos generales
        /// </summary>
        double totalGeneralDiscounts = 0;

        /// <summary>
        /// Campo que contiene los datos de la factura
        /// </summary>
        FacturaeFieldAndValues datos = null;

        /// <summary>
        /// Cultura de Office que determina los formatos numericos, fechas y monedas
        /// </summary>
        CultureInfo culturaOffice;

        /// <summary>
        /// Cultura de la factura que determina los formatos numericos, fechas y monedas
        /// </summary>
        CultureInfo culturaFactura;

        #endregion

        #region "Properties"
        /// <summary>
        /// Campo con la factura en formato UBL
        /// </summary>
        public Invoice Invoice { get; set; }

        #endregion

        #region "Constructors"


        /// <summary>
        /// Contructor por defecto
        /// </summary>
        public UBLGenerator()
        {
            culturaOffice = new CultureInfo(Globals.ThisAddIn.Application.LanguageSettings.get_LanguageID(Microsoft.Office.Core.MsoAppLanguageID.msoLanguageIDUI));
            culturaFactura = new CultureInfo("en-US");
            enumerateTables();
            Invoice = new Invoice();
        }

        /// <summary>
        /// Contructor con parámetros
        /// </summary>
        /// <param name="datos">Datos de la factura</param>
        public UBLGenerator(FacturaeFieldAndValues datos)
        {
            culturaOffice = new CultureInfo(Globals.ThisAddIn.Application.LanguageSettings.get_LanguageID(Microsoft.Office.Core.MsoAppLanguageID.msoLanguageIDUI));
            culturaFactura = new CultureInfo("en-US");
            enumerateTables();
            this.datos = datos;
            Invoice = new Invoice();
            header();
            seller();
            buyer();
            signatoryParty();
            lineasDetalle();
            descuentosGenerales();
            //irpfYDescuentos();
            descuentos();
            irpf();
            iva();
            resumenTotales();
        }

        #endregion

        #region "Creacion UBL"

        /// <summary>
        /// Método que genera los datos de cabecera de la factura
        /// </summary>
        public void header()
        {
            //CultureInfo c = new CultureInfo("es-ES");
            Invoice.UBLVersionID = "2.0";//datos.getValueByFieldName("SchemaVersion");
            Invoice.ID = datos.getValueByFieldName("IH_InvoiceSeriesCode") + "-" + datos.getValueByFieldName("IH_InvoiceNumber");
            //datos.getValueByFieldName("IH_InvoiceDocumentType");
            //Invoice.Note = "FC";//datos.getValueByFieldName("InvoiceIssuerType");
            if (datos.getValueByFieldName("IH_InvoiceClass").Equals("OO"))
            {
                Invoice.InvoiceTypeCode = "Comercial";
                Invoice.CopyIndicator = "false";
            }
            else if (datos.getValueByFieldName("IH_InvoiceClass").Equals("CO"))
            {
                Invoice.InvoiceTypeCode = "Comercial";
                Invoice.CopyIndicator = "true";
            }
            else if (datos.getValueByFieldName("IH_InvoiceClass").Equals("OR"))
            {
                Invoice.InvoiceTypeCode = "Rectificativa";
                Invoice.CopyIndicator = "false";
                Invoice.Note = datos.getValueByFieldName("CORR_ReasonDescription") + "/" + datos.getValueByFieldName("CORR_CorrectionMethodDescription");
                Invoice.BillingReference = new BillingReference();
                Invoice.BillingReference.InvoiceDocumentReference.ID = datos.getValueByFieldName("CORR_InvoiceSeriesCode") + "-" + datos.getValueByFieldName("CORR_InvoiceNumber");
                Invoice.BillingReference.InvoiceDocumentReference.IssueDate = DateTime.Parse(datos.getValueByFieldName("CORR_TaxPeriod_StartDate").Trim(x).Trim(), culturaOffice).ToString("yyyy-MM-dd");
            }
            else if (datos.getValueByFieldName("IH_InvoiceClass").Equals("CR"))
            {
                Invoice.InvoiceTypeCode = "Rectificativa";
                Invoice.CopyIndicator = "true";
                Invoice.Note = datos.getValueByFieldName("CORR_ReasonDescription") + "/" + datos.getValueByFieldName("CORR_CorrectionMethodDescription");
                Invoice.BillingReference = new BillingReference();
                Invoice.BillingReference.InvoiceDocumentReference.ID = datos.getValueByFieldName("CORR_InvoiceSeriesCode") + "-" + datos.getValueByFieldName("CORR_InvoiceNumber");
                Invoice.BillingReference.InvoiceDocumentReference.IssueDate = DateTime.Parse(datos.getValueByFieldName("CORR_TaxPeriod_StartDate").Trim(x).Trim(), culturaOffice).ToString("yyyy-MM-dd");
            }


            Invoice.IssueDate = DateTime.Parse(datos.getValueByFieldName("InvIssue_IssueDate").Trim(x).Trim(), culturaOffice).ToString("yyyy-MM-dd");
            Invoice.DocumentCurrencyCode = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
        }

        /// <summary>
        /// Método que genera los datos del emisor
        /// </summary>
        public void seller()
        {
            Invoice.AccountingSupplierParty.Party.PartyIdentification.ID = datos.getValueByFieldName("SP_TaxIdentificationNumber");

            if (datos.getValueByFieldName("SP_PersonTypeCode").Equals("J"))
            {
                Invoice.AccountingSupplierParty.Party.PartyName.Name = datos.getValueByFieldName("SP_CorporateName");
                Invoice.AccountingSupplierParty.Party.PartyLegalEntity = new PartyLegalEntity();
                Invoice.AccountingSupplierParty.Party.PartyLegalEntity.RegistrationName = datos.getValueByFieldName("SP_CorporateName");
                Invoice.AccountingSupplierParty.Party.PartyLegalEntity.CompanyID = datos.getValueByFieldName("SP_TaxIdentificationNumber");
                Invoice.AccountingSupplierParty.Party.PartyLegalEntity.RegistrationAddress.StreetName = datos.getValueByFieldName("SP_Address");
                Invoice.AccountingSupplierParty.Party.PartyLegalEntity.RegistrationAddress.CityName = datos.getValueByFieldName("SP_Town");
                Invoice.AccountingSupplierParty.Party.PartyLegalEntity.RegistrationAddress.PostalZone = datos.getValueByFieldName("SP_PostCode");
                Invoice.AccountingSupplierParty.Party.PartyLegalEntity.RegistrationAddress.CountrySubentity = datos.getValueByFieldName("SP_Province");
                Invoice.AccountingSupplierParty.Party.PartyLegalEntity.RegistrationAddress.Country.IdentificationCode = datos.getValueByFieldName("SP_CountryCode");
                if (!String.IsNullOrEmpty(datos.getValueByFieldName("SP_Telephone")))
                {
                    if (Invoice.AccountingSupplierParty.Party.Contact == null)
                    {
                        Invoice.AccountingSupplierParty.Party.Contact = new Contact();
                    }
                    Invoice.AccountingSupplierParty.Party.Contact.Telephone = datos.getValueByFieldName("SP_Telephone");

                }
                if (!String.IsNullOrEmpty(datos.getValueByFieldName("SP_email")))
                {
                    if (Invoice.AccountingSupplierParty.Party.Contact == null)
                    {
                        Invoice.AccountingSupplierParty.Party.Contact = new Contact();
                    }
                    Invoice.AccountingSupplierParty.Party.Contact.ElectronicMail = datos.getValueByFieldName("SP_email");
                }
            }
            else
            {
                Invoice.AccountingSupplierParty.Party.PartyName.Name = datos.getValueByFieldName("SP_Name") + " " + datos.getValueByFieldName("SP_FirstSurname") + " " + datos.getValueByFieldName("SP_SecondSurname");

                if (!String.IsNullOrEmpty(datos.getValueByFieldName("SP_Telephone")))
                {
                    if (Invoice.AccountingSupplierParty.Party.Contact == null)
                    {
                        Invoice.AccountingSupplierParty.Party.Contact = new Contact();
                    }
                    Invoice.AccountingSupplierParty.Party.Contact.Telephone = datos.getValueByFieldName("SP_Telephone");

                }
                if (!String.IsNullOrEmpty(datos.getValueByFieldName("SP_email")))
                {
                    if (Invoice.AccountingSupplierParty.Party.Contact == null)
                    {
                        Invoice.AccountingSupplierParty.Party.Contact = new Contact();
                    }
                    Invoice.AccountingSupplierParty.Party.Contact.ElectronicMail = datos.getValueByFieldName("SP_email");
                }
                Invoice.AccountingSupplierParty.Party.Person = new Person();
                Invoice.AccountingSupplierParty.Party.Person.FirstName = datos.getValueByFieldName("SP_Name");
                Invoice.AccountingSupplierParty.Party.Person.FamilyName = datos.getValueByFieldName("SP_FirstSurname") + " " + datos.getValueByFieldName("SP_SecondSurname");
                //Invoice.AccountingSupplierParty.Party.PartyTaxScheme = new PartyTaxScheme();
                //Invoice.AccountingSupplierParty.Party.PartyTaxScheme.RegistrationName = datos.getValueByFieldName("SP_Name");
                //Invoice.AccountingSupplierParty.Party.PartyTaxScheme.CompanyID = datos.getValueByFieldName("SP_TaxIdentificationNumber");
                Invoice.AccountingSupplierParty.Party.PostalAddress = new PostalAddress();
                Invoice.AccountingSupplierParty.Party.PostalAddress.StreetName = datos.getValueByFieldName("SP_Address");
                Invoice.AccountingSupplierParty.Party.PostalAddress.CityName = datos.getValueByFieldName("SP_Town");
                Invoice.AccountingSupplierParty.Party.PostalAddress.PostalZone = datos.getValueByFieldName("SP_PostCode");
                Invoice.AccountingSupplierParty.Party.PostalAddress.CountrySubentity = datos.getValueByFieldName("SP_Province");
                Invoice.AccountingSupplierParty.Party.PostalAddress.Country.IdentificationCode = datos.getValueByFieldName("SP_CountryCode");
            }

        }

        /// <summary>
        /// Método que genera los datos del receptor
        /// </summary>
        public void buyer()
        {
            Invoice.AccountingCustomerParty.Party.PartyIdentification.ID = datos.getValueByFieldName("BP_TaxIdentificationNumber");


            if (datos.getValueByFieldName("BP_PersonTypeCode").Equals("J"))
            {
                Invoice.AccountingCustomerParty.Party.PartyName.Name = datos.getValueByFieldName("BP_CorporateName");
                Invoice.AccountingCustomerParty.Party.PartyLegalEntity = new PartyLegalEntity();
                Invoice.AccountingCustomerParty.Party.PartyLegalEntity.RegistrationName = datos.getValueByFieldName("BP_CorporateName");
                Invoice.AccountingCustomerParty.Party.PartyLegalEntity.CompanyID = datos.getValueByFieldName("BP_TaxIdentificationNumber");
                Invoice.AccountingCustomerParty.Party.PartyLegalEntity.RegistrationAddress.StreetName = datos.getValueByFieldName("BP_Address");
                Invoice.AccountingCustomerParty.Party.PartyLegalEntity.RegistrationAddress.CityName = datos.getValueByFieldName("BP_Town");
                Invoice.AccountingCustomerParty.Party.PartyLegalEntity.RegistrationAddress.PostalZone = datos.getValueByFieldName("BP_PostCode");
                Invoice.AccountingCustomerParty.Party.PartyLegalEntity.RegistrationAddress.CountrySubentity = datos.getValueByFieldName("BP_Province");
                Invoice.AccountingCustomerParty.Party.PartyLegalEntity.RegistrationAddress.Country.IdentificationCode = datos.getValueByFieldName("BP_CountryCode");
                if (!String.IsNullOrEmpty(datos.getValueByFieldName("BP_Telephone")))
                {
                    if (Invoice.AccountingCustomerParty.Party.Contact == null)
                    {
                        Invoice.AccountingCustomerParty.Party.Contact = new Contact();
                    }
                    Invoice.AccountingCustomerParty.Party.Contact.Telephone = datos.getValueByFieldName("BP_Telephone");

                }
                if (!String.IsNullOrEmpty(datos.getValueByFieldName("BP_email")))
                {
                    if (Invoice.AccountingCustomerParty.Party.Contact == null)
                    {
                        Invoice.AccountingCustomerParty.Party.Contact = new Contact();
                    }
                    Invoice.AccountingCustomerParty.Party.Contact.ElectronicMail = datos.getValueByFieldName("BP_email");
                }
            }
            else
            {
                Invoice.AccountingCustomerParty.Party.PartyName.Name = datos.getValueByFieldName("BP_Name") + " " + datos.getValueByFieldName("BP_FirstSurname") + " " + datos.getValueByFieldName("BP_SecondSurname");

                if (!String.IsNullOrEmpty(datos.getValueByFieldName("BP_Telephone")))
                {
                    if (Invoice.AccountingCustomerParty.Party.Contact == null)
                    {
                        Invoice.AccountingCustomerParty.Party.Contact = new Contact();
                    }
                    Invoice.AccountingCustomerParty.Party.Contact.Telephone = datos.getValueByFieldName("BP_Telephone");

                }
                if (!String.IsNullOrEmpty(datos.getValueByFieldName("BP_email")))
                {
                    if (Invoice.AccountingCustomerParty.Party.Contact == null)
                    {
                        Invoice.AccountingCustomerParty.Party.Contact = new Contact();
                    }
                    Invoice.AccountingCustomerParty.Party.Contact.ElectronicMail = datos.getValueByFieldName("BP_email");
                }
                Invoice.AccountingCustomerParty.Party.Person = new Person();
                Invoice.AccountingCustomerParty.Party.Person.FirstName = datos.getValueByFieldName("BP_Name");
                Invoice.AccountingCustomerParty.Party.Person.FamilyName = datos.getValueByFieldName("BP_FirstSurname") + " " + datos.getValueByFieldName("BP_SecondSurname");
                //Invoice.AccountingCustomerParty.Party.PartyTaxScheme = new PartyTaxScheme();
                //Invoice.AccountingCustomerParty.Party.PartyTaxScheme.RegistrationName = datos.getValueByFieldName("BP_Name");
                //Invoice.AccountingCustomerParty.Party.PartyTaxScheme.CompanyID = datos.getValueByFieldName("BP_TaxIdentificationNumber");
                Invoice.AccountingCustomerParty.Party.PostalAddress = new PostalAddress();
                Invoice.AccountingCustomerParty.Party.PostalAddress.StreetName = datos.getValueByFieldName("BP_Address");
                Invoice.AccountingCustomerParty.Party.PostalAddress.CityName = datos.getValueByFieldName("BP_Town");
                Invoice.AccountingCustomerParty.Party.PostalAddress.PostalZone = datos.getValueByFieldName("BP_PostCode");
                Invoice.AccountingCustomerParty.Party.PostalAddress.CountrySubentity = datos.getValueByFieldName("BP_Province");
                Invoice.AccountingCustomerParty.Party.PostalAddress.Country.IdentificationCode = datos.getValueByFieldName("BP_CountryCode");

            }


        }


        /// <summary>
        /// Método que genera los datos del tercero
        /// </summary>
        public void signatoryParty()
        {
            if (datos.getValueByFieldName("InvoiceIssuerType").Equals("TE"))
            {
                Invoice.Signature.SignatoryParty.PartyIdentification.ID = datos.getValueByFieldName("TH_TaxIdentificationNumber");

                if (datos.getValueByFieldName("TH_PersonTypeCode").Equals("J"))
                {
                    Invoice.Signature.SignatoryParty.PartyName.Name = datos.getValueByFieldName("TH_CorporateName");
                    Invoice.Signature.SignatoryParty.PartyLegalEntity = new PartyLegalEntity();
                    Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationName = datos.getValueByFieldName("TH_CorporateName");
                    Invoice.Signature.SignatoryParty.PartyLegalEntity.CompanyID = datos.getValueByFieldName("TH_TaxIdentificationNumber");
                    Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.StreetName = datos.getValueByFieldName("TH_Address");
                    Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.CityName = datos.getValueByFieldName("TH_Town");
                    Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.PostalZone = datos.getValueByFieldName("TH_PostCode");
                    Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.CountrySubentity = datos.getValueByFieldName("TH_Province");
                    Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.Country.IdentificationCode = datos.getValueByFieldName("TH_CountryCode");
                    if (!String.IsNullOrEmpty(datos.getValueByFieldName("BP_Telephone")))
                    {
                        if (Invoice.Signature.SignatoryParty.Contact == null)
                        {
                            Invoice.Signature.SignatoryParty.Contact = new Contact();
                        }
                        Invoice.Signature.SignatoryParty.Contact.Telephone = datos.getValueByFieldName("BP_Telephone");

                    }
                    if (!String.IsNullOrEmpty(datos.getValueByFieldName("BP_email")))
                    {
                        if (Invoice.Signature.SignatoryParty.Contact == null)
                        {
                            Invoice.Signature.SignatoryParty.Contact = new Contact();
                        }
                        Invoice.Signature.SignatoryParty.Contact.ElectronicMail = datos.getValueByFieldName("BP_email");
                    }
                }
                else
                {
                    Invoice.Signature.SignatoryParty.PartyName.Name = datos.getValueByFieldName("TH_Name") + " " + datos.getValueByFieldName("TH_FirstSurname") + " " + datos.getValueByFieldName("TH_SecondSurname");

                    if (!String.IsNullOrEmpty(datos.getValueByFieldName("BP_Telephone")))
                    {
                        if (Invoice.Signature.SignatoryParty.Contact == null)
                        {
                            Invoice.Signature.SignatoryParty.Contact = new Contact();
                        }
                        Invoice.Signature.SignatoryParty.Contact.Telephone = datos.getValueByFieldName("BP_Telephone");

                    }
                    if (!String.IsNullOrEmpty(datos.getValueByFieldName("BP_email")))
                    {
                        if (Invoice.Signature.SignatoryParty.Contact == null)
                        {
                            Invoice.Signature.SignatoryParty.Contact = new Contact();
                        }
                        Invoice.Signature.SignatoryParty.Contact.ElectronicMail = datos.getValueByFieldName("BP_email");
                    }

                    Invoice.Signature.SignatoryParty.Person = new Person();
                    Invoice.Signature.SignatoryParty.Person.FirstName = datos.getValueByFieldName("TH_Name");
                    Invoice.Signature.SignatoryParty.Person.FamilyName = datos.getValueByFieldName("TH_FirstSurname") + " " + datos.getValueByFieldName("TH_SecondSurname");
                    //Invoice.Signature.SignatoryParty.PartyTaxScheme = new PartyTaxScheme();
                    //Invoice.Signature.SignatoryParty.PartyTaxScheme.RegistrationName = datos.getValueByFieldName("TH_Name");
                    //Invoice.Signature.SignatoryParty.PartyTaxScheme.CompanyID = datos.getValueByFieldName("TH_TaxIdentificationNumber");
                    Invoice.Signature.SignatoryParty.PostalAddress = new PostalAddress();
                    Invoice.Signature.SignatoryParty.PostalAddress.StreetName = datos.getValueByFieldName("TH_Address");
                    Invoice.Signature.SignatoryParty.PostalAddress.CityName = datos.getValueByFieldName("TH_Town");
                    Invoice.Signature.SignatoryParty.PostalAddress.PostalZone = datos.getValueByFieldName("TH_PostCode");
                    Invoice.Signature.SignatoryParty.PostalAddress.CountrySubentity = datos.getValueByFieldName("TH_Province");
                    Invoice.Signature.SignatoryParty.PostalAddress.Country.IdentificationCode = datos.getValueByFieldName("TH_CountryCode");

                }

            }
            else
            {
                Invoice.Signature.SignatoryParty.PartyIdentification.ID = datos.getValueByFieldName("SP_TaxIdentificationNumber");

                if (datos.getValueByFieldName("SP_PersonTypeCode").Equals("J"))
                {
                    Invoice.Signature.SignatoryParty.PartyName.Name = datos.getValueByFieldName("SP_CorporateName");
                    Invoice.Signature.SignatoryParty.PartyLegalEntity = new PartyLegalEntity();
                    Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationName = datos.getValueByFieldName("SP_CorporateName");
                    Invoice.Signature.SignatoryParty.PartyLegalEntity.CompanyID = datos.getValueByFieldName("SP_TaxIdentificationNumber");
                    Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.StreetName = datos.getValueByFieldName("SP_Address");
                    Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.BuildingNumber = datos.getValueByFieldName("SP_BuildingNumber");
                    Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.CityName = datos.getValueByFieldName("SP_Town");
                    Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.PostalZone = datos.getValueByFieldName("SP_PostCode");
                    Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.CountrySubentity = datos.getValueByFieldName("SP_Province");
                    Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.Country.IdentificationCode = datos.getValueByFieldName("SP_CountryCode");
                    if (!String.IsNullOrEmpty(datos.getValueByFieldName("SP_Telephone")))
                    {
                        if (Invoice.AccountingSupplierParty.Party.Contact == null)
                        {
                            Invoice.AccountingSupplierParty.Party.Contact = new Contact();
                        }
                        Invoice.AccountingSupplierParty.Party.Contact.Telephone = datos.getValueByFieldName("SP_Telephone");

                    }
                    if (!String.IsNullOrEmpty(datos.getValueByFieldName("SP_email")))
                    {
                        if (Invoice.AccountingSupplierParty.Party.Contact == null)
                        {
                            Invoice.AccountingSupplierParty.Party.Contact = new Contact();
                        }
                        Invoice.AccountingSupplierParty.Party.Contact.ElectronicMail = datos.getValueByFieldName("SP_email");
                    }
                }
                else
                {
                    Invoice.Signature.SignatoryParty.PartyName.Name = datos.getValueByFieldName("SP_Name") + " " + datos.getValueByFieldName("SP_FirstSurname") + " " + datos.getValueByFieldName("SP_SecondSurname");

                    if (!String.IsNullOrEmpty(datos.getValueByFieldName("SP_Telephone")))
                    {
                        if (Invoice.AccountingSupplierParty.Party.Contact == null)
                        {
                            Invoice.AccountingSupplierParty.Party.Contact = new Contact();
                        }
                        Invoice.AccountingSupplierParty.Party.Contact.Telephone = datos.getValueByFieldName("SP_Telephone");

                    }
                    if (!String.IsNullOrEmpty(datos.getValueByFieldName("SP_email")))
                    {
                        if (Invoice.AccountingSupplierParty.Party.Contact == null)
                        {
                            Invoice.AccountingSupplierParty.Party.Contact = new Contact();
                        }
                        Invoice.AccountingSupplierParty.Party.Contact.ElectronicMail = datos.getValueByFieldName("SP_email");
                    }

                    Invoice.Signature.SignatoryParty.Person = new Person();
                    Invoice.Signature.SignatoryParty.Person.FirstName = datos.getValueByFieldName("SP_Name");
                    Invoice.Signature.SignatoryParty.Person.FamilyName = datos.getValueByFieldName("SP_FirstSurname") + " " + datos.getValueByFieldName("SP_SecondSurname");
                    //Invoice.Signature.SignatoryParty.PartyTaxScheme = new PartyTaxScheme();
                    //Invoice.Signature.SignatoryParty.PartyTaxScheme.RegistrationName = datos.getValueByFieldName("SP_Name");
                    //Invoice.Signature.SignatoryParty.PartyTaxScheme.CompanyID = datos.getValueByFieldName("SP_TaxIdentificationNumber");
                    Invoice.Signature.SignatoryParty.PostalAddress = new PostalAddress();
                    Invoice.Signature.SignatoryParty.PostalAddress.StreetName = datos.getValueByFieldName("SP_Address");
                    Invoice.Signature.SignatoryParty.PostalAddress.BuildingNumber = datos.getValueByFieldName("SP_BuildingNumber");
                    Invoice.Signature.SignatoryParty.PostalAddress.CityName = datos.getValueByFieldName("SP_Town");
                    Invoice.Signature.SignatoryParty.PostalAddress.PostalZone = datos.getValueByFieldName("SP_PostCode");
                    Invoice.Signature.SignatoryParty.PostalAddress.CountrySubentity = datos.getValueByFieldName("SP_Province");
                    Invoice.Signature.SignatoryParty.PostalAddress.Country.IdentificationCode = datos.getValueByFieldName("SP_CountryCode");

                }

            }
        }


        /// <summary>
        /// Método que genera los descuentos generales
        /// </summary>
        public void descuentosGenerales()
        {
            AllowanceCharge descuentoGeneral = null;
            datos.generalDiscount = getGeneralDiscounts();
            if (datos.generalDiscount != null)
            {
                for (int i = 0; i < datos.generalDiscount.Count; i++)
                {
                    if (!double.Parse(datos.generalDiscount[i].discountRate, culturaOffice.NumberFormat).Equals(double.Parse("0", culturaOffice.NumberFormat)))
                    {
                        descuentoGeneral = new AllowanceCharge();
                        descuentoGeneral.AllowanceChargeReasonCode = "01";
                        descuentoGeneral.AllowanceChargeReason = datos.generalDiscount[i].Reason;
                        descuentoGeneral.BaseAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.generalDiscount[i].baseImponible);
                        descuentoGeneral.Amount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.generalDiscount[i].totalDescuento);
                        descuentoGeneral.MultiplierFactorNumeric = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.generalDiscount[i].discountRate);
                        descuentoGeneral.BaseAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                        descuentoGeneral.Amount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                        if (Invoice.AllowanceCharge == null)
                        {
                            Invoice.AllowanceCharge = new List<AllowanceCharge>();
                        }
                        Invoice.AllowanceCharge.Add(descuentoGeneral);
                    }
                }
            }



        }

        /// <summary>
        /// Método que genera los descuentos a nivel de linea
        /// </summary>
        public void descuentos()
        {
            AllowanceCharge descuento = null;
            for (int i = 0; i < datos.lineDetails.Count; i++)
            {
                descuento = new AllowanceCharge();
                if (!String.IsNullOrEmpty(datos.lineDetails[i].DiscountRate) && (!double.Parse(datos.lineDetails[i].DiscountRate, culturaOffice.NumberFormat).Equals(double.Parse("0", culturaOffice.NumberFormat))))
                {
                    if (!addIfExist(datos.lineDetails[i].DiscountRate, datos.lineDetails[i].DiscountAmount, datos.lineDetails[i].BaseImponible, 2))
                    {
                        descuento.AllowanceChargeReasonCode = "02";
                        descuento.AllowanceChargeReason = "Discount";
                        descuento.MultiplierFactorNumeric = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].DiscountRate);
                        descuento.BaseAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].BaseImponible);//String.Format(numberFormat, "{0:0.00}", datos.lineDetails[i].BaseImponible);
                        descuento.BaseAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                        descuento.Amount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].DiscountAmount);
                        descuento.Amount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                        if (Invoice.AllowanceCharge == null)
                        {
                            Invoice.AllowanceCharge = new List<AllowanceCharge>();
                        }
                        Invoice.AllowanceCharge.Add(descuento);
                    }
                }
            }
        }


        /// <summary>
        /// Método que genera los impuestos retenidos
        /// </summary>
        public void irpf()
        {
            TaxTotal irpf = null;
            for (int i = 0; i < datos.lineDetails.Count; i++)
            {
                irpf = new TaxTotal();
                if (!String.IsNullOrEmpty(datos.lineDetails[i].IRPFTaxRate) && (!double.Parse(datos.lineDetails[i].IRPFTaxRate, culturaOffice.NumberFormat).Equals(double.Parse("0",culturaOffice.NumberFormat))))
                {
                    if (!addIfExist(datos.lineDetails[i].IRPFTaxRate, datos.lineDetails[i].IRPFAmount, datos.lineDetails[i].BaseImponible, 1))
                    {
                        irpf.TaxAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].IRPFAmount);
                        irpf.TaxAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                        irpf.TaxSubtotal.TaxableAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].BaseImponible);//datos.lineDetails[i].BaseImponible;
                        irpf.TaxSubtotal.TaxableAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                        irpf.TaxSubtotal.TaxAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].IRPFAmount);
                        irpf.TaxSubtotal.TaxAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                        irpf.TaxSubtotal.TaxCategory.Percent = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].IRPFTaxRate);
                        irpf.TaxSubtotal.TaxCategory.TaxScheme.TaxTypeCode = "IRPF";
                        if (Invoice.TaxTotal == null)
                        {
                            Invoice.TaxTotal = new List<TaxTotal>();
                        }
                        Invoice.TaxTotal.Add(irpf);

                    }
                }
            }
        }


        /// <summary>
        /// Método que genera los impuestos repercutidos
        /// </summary>
        public void iva()
        {
            TaxTotal taxTotal = null;
            for (int i = 0; i < datos.lineDetails.Count; i++)
            {

                if (!String.IsNullOrEmpty(datos.lineDetails[i].TaxRate) && (!double.Parse(datos.lineDetails[i].TaxRate, culturaOffice.NumberFormat).Equals(double.Parse("0", culturaOffice.NumberFormat))))
                {
                    if (!addIfExist(datos.lineDetails[i].TaxRate, datos.lineDetails[i].TaxAmount, datos.lineDetails[i].BaseImponible, 0))
                    {
                        taxTotal = new TaxTotal();
                        taxTotal.TaxAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].TaxAmount);
                        taxTotal.TaxAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                        taxTotal.TaxSubtotal.TaxableAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].BaseImponible);//datos.lineDetails[i].BaseImponible;
                        taxTotal.TaxSubtotal.TaxableAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                        taxTotal.TaxSubtotal.TaxAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].TaxAmount);
                        taxTotal.TaxSubtotal.TaxAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                        taxTotal.TaxSubtotal.TaxCategory.Percent = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].TaxRate);
                        taxTotal.TaxSubtotal.TaxCategory.TaxScheme.TaxTypeCode = "VAT";
                        if (Invoice.TaxTotal == null)
                        {
                            Invoice.TaxTotal = new List<TaxTotal>();
                        }
                        Invoice.TaxTotal.Add(taxTotal);
                    }
                }
            }
        }


        /// <summary>
        /// Método que genera el resumen de totales
        /// </summary>
        public void resumenTotales()
        {
            Invoice.LegalMonetaryTotal.LineExtensionAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", totalGrossAmountBeforeTaxes);
            Invoice.LegalMonetaryTotal.LineExtensionAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
            Invoice.LegalMonetaryTotal.TaxExclusiveAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", totalTaxOutputs);
            Invoice.LegalMonetaryTotal.TaxExclusiveAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
            Invoice.LegalMonetaryTotal.TaxInclusiveAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", totalGrossAmount);
            Invoice.LegalMonetaryTotal.TaxInclusiveAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
            Invoice.LegalMonetaryTotal.AllowanceTotalAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", totalGeneralDiscounts);
            Invoice.LegalMonetaryTotal.AllowanceTotalAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
            Invoice.LegalMonetaryTotal.PayableAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", totalGrossAmount - totalGeneralDiscounts + totalTaxOutputs - totalIRPF);
            Invoice.LegalMonetaryTotal.PayableAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");

        }


        /// <summary>
        /// Método que genera las linea de detalle de la factura
        /// </summary>
        public void lineasDetalle()
        {
            InvoiceLine line = null;
            AllowanceCharge descuento = null;
            TaxTotal irpf = null;
            TaxTotal iva = null;
            datos.lineDetails = getItems();
            for (int i = 0; i < datos.lineDetails.Count; i++)
            {

                line = new InvoiceLine();
                line.ID = (i + 1).ToString();
                line.InvoicedQuantity = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].Quantity);
                line.LineExtensionAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].BaseImponible);
                line.LineExtensionAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                if (!String.IsNullOrEmpty(datos.lineDetails[i].DiscountRate) && (!double.Parse(datos.lineDetails[i].DiscountRate, culturaOffice.NumberFormat).Equals(double.Parse("0", culturaOffice.NumberFormat))))
                {
                    descuento = new AllowanceCharge();
                    if (line.AllowanceCharge == null)
                    {
                        line.AllowanceCharge = new List<AllowanceCharge>();
                    }
                    descuento.AllowanceChargeReasonCode = "02";
                    descuento.AllowanceChargeReason = "Discount";
                    descuento.MultiplierFactorNumeric = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].DiscountRate);
                    descuento.BaseAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].BaseImponible);
                    descuento.BaseAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                    descuento.Amount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].DiscountAmount);
                    descuento.Amount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                    line.AllowanceCharge.Add(descuento);
                }
                if (!String.IsNullOrEmpty(datos.lineDetails[i].IRPFTaxRate) && (!double.Parse(datos.lineDetails[i].IRPFTaxRate, culturaOffice.NumberFormat).Equals(double.Parse("0", culturaOffice.NumberFormat))))
                {
                    irpf = new TaxTotal();
                    if (line.TaxTotal == null)
                    {
                        line.TaxTotal = new List<TaxTotal>();
                    }
                    irpf.TaxAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].IRPFAmount);
                    irpf.TaxAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                    irpf.TaxSubtotal.TaxableAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].BaseImponible);
                    irpf.TaxSubtotal.TaxableAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                    irpf.TaxSubtotal.TaxAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].IRPFAmount);
                    irpf.TaxSubtotal.TaxAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                    irpf.TaxSubtotal.TaxCategory.Percent = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].IRPFTaxRate);
                    irpf.TaxSubtotal.TaxCategory.TaxScheme.TaxTypeCode = "IRPF";
                    line.TaxTotal.Add(irpf);
                }
                if (!String.IsNullOrEmpty(datos.lineDetails[i].TaxRate) && (!double.Parse(datos.lineDetails[i].TaxRate, culturaOffice.NumberFormat).Equals(double.Parse("0", culturaOffice.NumberFormat))))
                {
                    iva = new TaxTotal();
                    if (line.TaxTotal == null)
                    {
                        line.TaxTotal = new List<TaxTotal>();
                    }
                    iva.TaxAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].TaxAmount);
                    iva.TaxAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                    iva.TaxSubtotal.TaxableAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].BaseImponible);
                    iva.TaxSubtotal.TaxableAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                    iva.TaxSubtotal.TaxAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].TaxAmount);
                    iva.TaxSubtotal.TaxAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                    iva.TaxSubtotal.TaxCategory.Percent = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].TaxRate);
                    iva.TaxSubtotal.TaxCategory.TaxScheme.TaxTypeCode = "VAT";
                    line.TaxTotal.Add(iva);
                }

                if (!String.IsNullOrEmpty(datos.lineDetails[i].TransactionDate))
                {
                    line.Delivery = new Delivery();
                    //CultureInfo c = new CultureInfo("es-ES");
                    line.Delivery.ActualDeliveryDate = DateTime.Parse(datos.lineDetails[i].TransactionDate.Trim(x).Trim(), culturaOffice).ToString("yyyy-MM-dd");
                }

                line.Item.Name = datos.lineDetails[i].Descripcion;
                line.Price.PriceAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.lineDetails[i].UnitPriceWithoutTax);
                line.Price.PriceAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                Invoice.InvoiceLine.Add(line);
            }

        }

        /// <summary>
        /// Método que calcula el valor de los descuentos generales
        /// </summary>
        /// <returns>Lista de descuentos generales</returns>
        private List<GeneralDiscountType> getGeneralDiscounts()
        {
            List<GeneralDiscountType> generalDiscounts = null;

            if (document.Tables[t3].Rows.Count > 3)
            {
                generalDiscounts = new List<GeneralDiscountType>();
                GeneralDiscountType discount = null;
                double discountAmount = 0;

                for (int i = 3; i < document.Tables[t3].Rows.Count; i++)
                {
                    discount = new GeneralDiscountType();
                    double discountRate = Round3(double.Parse(document.Tables[t3].Rows[i].Cells[2].Range.Text.Trim(x).Trim(), culturaOffice.NumberFormat), 2);

                    if (discountRate != 0)
                    {
                        discountAmount = Round3(((double.Parse(datos.Totals.TotalGrossAmount, culturaOffice.NumberFormat) * discountRate) / 100), 2);
                    }

                    totalGeneralDiscounts += Round3(discountAmount, 2);
                    discount.Reason = document.Tables[t3].Rows[i].Cells[1].Range.Text.Trim(x).Trim();
                    discount.discountRate = String.Format(culturaFactura.NumberFormat, "{0:0.00}", discountRate);
                    discount.totalDescuento = String.Format(culturaFactura.NumberFormat, "{0:0.00}", discountAmount);
                    discount.baseImponible = String.Format(culturaFactura.NumberFormat, "{0:0.00}", datos.Totals.TotalGrossAmount);
                    generalDiscounts.Add(discount);
                }
                totalGrossAmountBeforeTaxes = totalGrossAmount - totalGeneralDiscounts;
            }

            return generalDiscounts;
        }



        /// <summary>
        /// Método que comprueba si un tipo de impuesto existe, con lo cual incrementa el importe
        /// o por el contrario no existe, lo creo nuevo
        /// </summary>
        /// <param name="percent">Porcentaje del impuesto</param>
        /// <param name="amount">Importe</param>
        /// <param name="baseImponible">BaseImponible</param>
        /// <param name="type">Tipo de impuesto</param>
        /// <returns>True o false si existe el tipo de impuesto</returns>
        private bool addIfExist(String iva, String amount, String baseImponible, int type)
        {
            switch (type)
            {
                //Tipo IVA
                case 0:
                    {
                        if (Invoice.TaxTotal != null)
                        {
                            for (int i = 0; i < Invoice.TaxTotal.Count; i++)
                            {
                                if (iva.Equals(Invoice.TaxTotal[i].TaxSubtotal.TaxCategory.Percent) && Invoice.TaxTotal[i].TaxSubtotal.TaxCategory.TaxScheme.TaxTypeCode.Equals("VAT"))
                                {
                                    Invoice.TaxTotal[i].TaxAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", Round3((double.Parse(Invoice.TaxTotal[i].TaxAmount.Value, culturaFactura.NumberFormat) + double.Parse(amount, culturaFactura.NumberFormat)), 2));
                                    Invoice.TaxTotal[i].TaxAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                                    Invoice.TaxTotal[i].TaxSubtotal.TaxAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", Invoice.TaxTotal[i].TaxAmount.Value);
                                    Invoice.TaxTotal[i].TaxSubtotal.TaxAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                                    Invoice.TaxTotal[i].TaxSubtotal.TaxableAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", Round3((double.Parse(Invoice.TaxTotal[i].TaxSubtotal.TaxableAmount.Value, culturaFactura.NumberFormat) + double.Parse(baseImponible, culturaFactura.NumberFormat)), 2));
                                    return true;
                                }
                            }
                        }

                    } break;
                //Tipo IRPF
                case 1:
                    {
                        if (Invoice.TaxTotal != null)
                        {
                            for (int i = 0; i < Invoice.TaxTotal.Count; i++)
                            {
                                if (iva.Equals(Invoice.TaxTotal[i].TaxSubtotal.TaxCategory.Percent) && Invoice.TaxTotal[i].TaxSubtotal.TaxCategory.TaxScheme.TaxTypeCode.Equals("IRPF"))
                                {
                                    Invoice.TaxTotal[i].TaxAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", Round3((double.Parse(Invoice.TaxTotal[i].TaxAmount.Value, culturaFactura.NumberFormat) + double.Parse(amount, culturaFactura.NumberFormat)), 2));
                                    Invoice.TaxTotal[i].TaxAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                                    Invoice.TaxTotal[i].TaxSubtotal.TaxAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", Invoice.TaxTotal[i].TaxAmount.Value);
                                    Invoice.TaxTotal[i].TaxSubtotal.TaxAmount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                                    Invoice.TaxTotal[i].TaxSubtotal.TaxableAmount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", Round3((double.Parse(Invoice.TaxTotal[i].TaxSubtotal.TaxableAmount.Value, culturaFactura.NumberFormat) + double.Parse(baseImponible, culturaFactura.NumberFormat)), 2));
                                    return true;
                                }
                            }
                        }

                    } break;
                //Tipo Descuento
                case 2:
                    {
                        if (Invoice.AllowanceCharge != null)
                        {
                            for (int i = 0; i < Invoice.AllowanceCharge.Count; i++)
                            {
                                if (Invoice.AllowanceCharge[i].AllowanceChargeReasonCode.Equals("02") && iva.Equals(Invoice.AllowanceCharge[i].MultiplierFactorNumeric))
                                {
                                    Invoice.AllowanceCharge[i].Amount.Value = String.Format(culturaFactura.NumberFormat, "{0:0.00}", Round3((double.Parse(Invoice.AllowanceCharge[i].Amount.Value, culturaFactura.NumberFormat) + double.Parse(amount,culturaFactura.NumberFormat)), 2));
                                    Invoice.AllowanceCharge[i].Amount.currencyID = datos.getValueByFieldName("InvIssue_InvoiceCurrencyCode");
                                    return true;
                                }
                            }
                        }

                    } break;
            }

            return false;
        }



        /// <summary>
        /// Se encarga de realzar los cálculos y operaciones necesarias para registrar cada uno de los detalles 
        /// en el listado de ítemes de la factura
        /// </summary>
        /// <returns>El Listado cargado con las líneas de detalle</returns>
        private List<TypeLineDetails> getItems()
        {
            List<TypeLineDetails> items = new List<TypeLineDetails>();


            if (document.Tables[t2].Rows.Count > 3)
            {

                /*recorremos todas las filas de la tabla para agregar los registros a la lista de itemes*/

                for (int i = 3; i < document.Tables[t2].Rows.Count; i++)
                {

                    TypeLineDetails item = new TypeLineDetails();

                    double Quantity = double.Parse(document.Tables[t2].Rows[i].Cells[3].Range.Text.Trim(x).Trim(), culturaOffice.NumberFormat);

                    double unitPriceWithoutTax = Round3(double.Parse(document.Tables[t2].Rows[i].Cells[4].Range.Text.Trim(x).Trim(), culturaOffice.NumberFormat), 2);

                    double discountRate = Round3(double.Parse(document.Tables[t2].Rows[i].Cells[5].Range.Text.Trim(x).Trim(), culturaOffice.NumberFormat), 2);

                    double taxRate = Round3(double.Parse(document.Tables[t2].Rows[i].Cells[6].Range.Text.Trim(x).Trim(), culturaOffice.NumberFormat), 2);

                    double IRPFTaxRate = Round3(double.Parse(document.Tables[t2].Rows[i].Cells[7].Range.Text.Trim(x).Trim(), culturaOffice.NumberFormat), 2);

                    double discountAmount = Round3(((Quantity * unitPriceWithoutTax) * discountRate) / 100, 2);

                    double baseImponible = Round3((Quantity * unitPriceWithoutTax) - discountAmount, 2);

                    double IVAAmount = Round3(baseImponible * taxRate / 100, 2);

                    double IRPFAmount = Round3(baseImponible * (IRPFTaxRate / 100), 2);

                    //double total = Round3((baseImponible + (IVAAmount - IRPFAmount)), 2);

                    //CultureInfo cult = new CultureInfo("es-ES");

                    DateTime transactionDate = DateTime.Parse(document.Tables[t2].Rows[i].Cells[1].Range.Text.Trim(x).Trim(), culturaOffice);

                    item.TransactionDate = transactionDate.ToString("yyyy-MM-dd");
                    item.Descripcion = document.Tables[t2].Rows[i].Cells[2].Range.Text.Trim(x).Trim();
                    item.Quantity = int.Parse(Quantity.ToString()).ToString();
                    item.UnitPriceWithoutTax = String.Format(culturaFactura.NumberFormat, "{0:0.00}", Round3(double.Parse(document.Tables[t2].Rows[i].Cells[4].Range.Text.Trim(x).Trim(), culturaOffice.NumberFormat), 2));
                    item.DiscountRate = String.Format(culturaFactura.NumberFormat, "{0:0.00}", Round3(double.Parse(document.Tables[t2].Rows[i].Cells[5].Range.Text.Trim(x).Trim(), culturaOffice.NumberFormat), 2));
                    item.TaxRate = String.Format(culturaFactura.NumberFormat, "{0:0.00}", Round3(double.Parse(document.Tables[t2].Rows[i].Cells[6].Range.Text.Trim(x).Trim(), culturaOffice.NumberFormat), 2));
                    item.IRPFTaxRate = String.Format(culturaFactura.NumberFormat, "{0:0.00}", Round3(double.Parse(document.Tables[t2].Rows[i].Cells[7].Range.Text.Trim(x).Trim(), culturaOffice.NumberFormat), 2));
                    item.BaseImponible = String.Format(culturaFactura.NumberFormat, "{0:0.00}", Round3(double.Parse(document.Tables[t2].Rows[i].Cells[8].Range.Text.Trim(x).Trim(), culturaOffice.NumberFormat), 2));
                    item.TotalImport = String.Format(culturaFactura.NumberFormat, "{0:0.00}", Round3(double.Parse(document.Tables[t2].Rows[i].Cells[9].Range.Text.Trim(x).Trim(), culturaOffice.NumberFormat), 2));

                    item.DiscountAmount = String.Format(culturaFactura.NumberFormat, "{0:0.00}", discountAmount);
                    item.IRPFAmount = String.Format(culturaFactura.NumberFormat, "{0:0.00}", IRPFAmount);
                    item.TaxAmount = String.Format(culturaFactura.NumberFormat, "{0:0.00}", IVAAmount);

                    //totalGrossAmount += Round3(total, 2);
                    totalGrossAmount += Round3(baseImponible, 2);
                    totalTaxOutputs += Round3(IVAAmount, 2);
                    totalIRPF += Round3(IRPFAmount, 2);
                    totalGrossAmountBeforeTaxes += Round3(baseImponible, 2);
                    //totalGeneralDiscounts = Round3(discountAmount,2);
                    items.Add(item);
                }
                datos.Totals.TotalGrossAmount += String.Format(culturaFactura.NumberFormat, "{0:0.00}", totalGrossAmount);
                datos.Totals.TotalTaxOutputs += String.Format(culturaFactura.NumberFormat, "{0:0.00}", totalTaxOutputs);
                //datos.Totals.TotalGrossAmountBeforeTaxes += String.Format("{0:0.00}", totalGrossAmountBeforeTaxes);
                //datos.Totals.TotalGeneralDiscounts = String.Format("{0:0.00}", totalGeneralDiscounts);
            }
            else
            {
                ControlMessages controlM = ControlMessages.getInstance();

                throw new Exception(controlM.getMessage(ControlMessages.Msg.ErrorInvoiceHaveNotDetails));
            }

            return items;
        }


        #endregion

        #region "Importacion UBL"

        /// <summary>
        /// Método encargado de generar un objeto CII con los datos cargados de una factura
        /// </summary>
        public void loadData()
        {
            setHeader();
            setSeller();
            setBuyer();
            if (!Invoice.AccountingSupplierParty.Party.PartyIdentification.ID.ToLower().Equals(Invoice.Signature.SignatoryParty.PartyIdentification.ID.ToLower()))
            {
                setSignatoryParty();
            }
            setlineasDetalles();
            setDecuentosGenerales();
            setTotales();
        }

        /// <summary>
        /// Método que importa los datos de cabecera
        /// </summary>
        public void setHeader()
        {
            setControlValue("SchemaVersion", Invoice.UBLVersionID);
            setControlValue("IH_InvoiceSeriesCode", Invoice.ID.Substring(0, Invoice.ID.IndexOf("-")));
            setControlValue("IH_InvoiceNumber", Invoice.ID.Substring(Invoice.ID.IndexOf("-") + 1));
            DateTime dateTime = Convert.ToDateTime(Invoice.IssueDate, culturaOffice);
            setControlValue("InvIssue_IssueDate", dateTime.ToString(culturaOffice.DateTimeFormat.ShortDatePattern));
            setControlValue("InvIssue_InvoiceCurrencyCode", Invoice.DocumentCurrencyCode);
            setControlValue("ExchangeRate", getExchangeRate());
            if (Invoice.CopyIndicator.ToLower().Equals("false"))
            {
                setControlValue("IH_InvoiceClass", "OO");
            }
            else if (Invoice.CopyIndicator.ToLower().Equals("true"))
            {
                setControlValue("IH_InvoiceClass", "CO");
            }
            if (Invoice.InvoiceTypeCode.ToLower().Equals("Rectificativa".ToLower()))
            {
                String[] corrective = Invoice.Note.Split(new Char[] { '/' });
                if (corrective.Length > 0)
                {
                    setControlValue("CORR_ReasonDescription", corrective[0]);
                }
                if (corrective.Length > 1)
                {
                    setControlValue("CORR_CorrectionMethodDescription", corrective[1]);
                }
                setControlValue("CORR_InvoiceSeriesCode", Invoice.BillingReference.InvoiceDocumentReference.ID.Substring(0, Invoice.BillingReference.InvoiceDocumentReference.ID.IndexOf("-")));
                setControlValue("CORR_InvoiceNumber", Invoice.BillingReference.InvoiceDocumentReference.ID.Substring(Invoice.BillingReference.InvoiceDocumentReference.ID.IndexOf("-") + 1));
                if (Invoice.CopyIndicator.ToLower().Equals("false"))
                {
                    setControlValue("IH_InvoiceClass", "OR");
                }
                else if (Invoice.CopyIndicator.ToLower().Equals("true"))
                {
                    setControlValue("IH_InvoiceClass", "CR");
                }
                setControlValue("CORR_TaxPeriod_StartDate", Convert.ToDateTime(Invoice.BillingReference.InvoiceDocumentReference.IssueDate, culturaOffice).ToString(culturaOffice.DateTimeFormat.ShortDatePattern));
            }
        }

        /// <summary>
        /// Método que importa los datos del emisor
        /// </summary>
        public void setSeller()
        {
            if (Invoice.AccountingSupplierParty.Party.PartyLegalEntity != null)
            {
                setControlValue("SP_PersonTypeCode", "J");
                setControlValue("SP_CorporateName", Invoice.AccountingSupplierParty.Party.PartyLegalEntity.RegistrationName);
                setControlValue("SP_TaxIdentificationNumber", Invoice.AccountingSupplierParty.Party.PartyIdentification.ID);
                setControlValue("SP_Address", Invoice.AccountingSupplierParty.Party.PartyLegalEntity.RegistrationAddress.StreetName);
                setControlValue("SP_BuildingNumber", Invoice.AccountingSupplierParty.Party.PartyLegalEntity.RegistrationAddress.BuildingNumber);
                setControlValue("SP_Town", Invoice.AccountingSupplierParty.Party.PartyLegalEntity.RegistrationAddress.CityName);
                setControlValue("SP_PostCode", Invoice.AccountingSupplierParty.Party.PartyLegalEntity.RegistrationAddress.PostalZone);
                setControlValue("SP_Province", Invoice.AccountingSupplierParty.Party.PartyLegalEntity.RegistrationAddress.CountrySubentity);
                setControlValue("SP_CountryCode", Invoice.AccountingSupplierParty.Party.PartyLegalEntity.RegistrationAddress.Country.IdentificationCode);
                if (Invoice.AccountingSupplierParty.Party.Contact.Telephone != null)
                {
                    setControlValue("SP_Telephone", Invoice.AccountingSupplierParty.Party.Contact.Telephone);
                }
                if (Invoice.AccountingSupplierParty.Party.Contact.ElectronicMail != null)
                {
                    setControlValue("SP_email", Invoice.AccountingSupplierParty.Party.Contact.ElectronicMail);
                }
            }
            else
            {
                setControlValue("SP_PersonTypeCode", "F");
                setControlValue("SP_TaxIdentificationNumber", Invoice.AccountingSupplierParty.Party.PartyIdentification.ID);
                setControlValue("SP_Name", Invoice.AccountingSupplierParty.Party.Person.FirstName);
                setControlValue("SP_FirstSurname", Invoice.AccountingSupplierParty.Party.Person.FamilyName);
                if (Invoice.AccountingSupplierParty.Party.PartyTaxScheme != null)
                {
                    setControlValue("SP_Name", Invoice.AccountingSupplierParty.Party.PartyTaxScheme.RegistrationName);
                    setControlValue("SP_TaxIdentificationNumber", Invoice.AccountingSupplierParty.Party.PartyTaxScheme.CompanyID);
                }
                if (Invoice.AccountingSupplierParty.Party.PostalAddress != null)
                {
                    setControlValue("SP_Address", Invoice.AccountingSupplierParty.Party.PostalAddress.StreetName);
                    setControlValue("SP_BuildingNumber", Invoice.AccountingSupplierParty.Party.PostalAddress.BuildingNumber);
                    setControlValue("SP_Town", Invoice.AccountingSupplierParty.Party.PostalAddress.CityName);
                    setControlValue("SP_PostCode", Invoice.AccountingSupplierParty.Party.PostalAddress.PostalZone);
                    setControlValue("SP_Province", Invoice.AccountingSupplierParty.Party.PostalAddress.CountrySubentity);
                    setControlValue("SP_CountryCode", Invoice.AccountingSupplierParty.Party.PostalAddress.Country.IdentificationCode);
                }
                if (Invoice.AccountingSupplierParty.Party.Contact != null)
                {
                    if (Invoice.AccountingSupplierParty.Party.Contact.Telephone != null)
                    {
                        setControlValue("SP_Telephone", Invoice.AccountingSupplierParty.Party.Contact.Telephone);
                    }
                    if (Invoice.AccountingSupplierParty.Party.Contact.ElectronicMail != null)
                    {
                        setControlValue("SP_email", Invoice.AccountingSupplierParty.Party.Contact.ElectronicMail);
                    }
                }
            }
        }

        /// <summary>
        /// Método que importa los datos del receptor
        /// </summary>
        public void setBuyer()
        {
            if (Invoice.AccountingCustomerParty.Party.PartyLegalEntity != null)
            {
                setControlValue("BP_PersonTypeCode", "J");
                setControlValue("BP_CorporateName", Invoice.AccountingCustomerParty.Party.PartyLegalEntity.RegistrationName);
                setControlValue("BP_TaxIdentificationNumber", Invoice.AccountingCustomerParty.Party.PartyIdentification.ID);
                setControlValue("BP_Address", Invoice.AccountingCustomerParty.Party.PartyLegalEntity.RegistrationAddress.StreetName);
                setControlValue("BP_BuildingNumber", Invoice.AccountingCustomerParty.Party.PartyLegalEntity.RegistrationAddress.BuildingNumber);
                setControlValue("BP_Town", Invoice.AccountingCustomerParty.Party.PartyLegalEntity.RegistrationAddress.CityName);
                setControlValue("BP_PostCode", Invoice.AccountingCustomerParty.Party.PartyLegalEntity.RegistrationAddress.PostalZone);
                setControlValue("BP_Province", Invoice.AccountingCustomerParty.Party.PartyLegalEntity.RegistrationAddress.CountrySubentity);
                setControlValue("BP_CountryCode", Invoice.AccountingCustomerParty.Party.PartyLegalEntity.RegistrationAddress.Country.IdentificationCode);
                if (Invoice.AccountingCustomerParty.Party.Contact != null)
                {
                    if (Invoice.AccountingCustomerParty.Party.Contact.Telephone != null)
                    {
                        setControlValue("BP_Telephone", Invoice.AccountingCustomerParty.Party.Contact.Telephone);
                    }
                    if (Invoice.AccountingCustomerParty.Party.Contact.ElectronicMail != null)
                    {
                        setControlValue("BP_email", Invoice.AccountingCustomerParty.Party.Contact.ElectronicMail);
                    }
                }
            }
            else
            {
                setControlValue("BP_PersonTypeCode", "F");
                setControlValue("BP_TaxIdentificationNumber", Invoice.AccountingCustomerParty.Party.PartyIdentification.ID);
                setControlValue("BP_Name", Invoice.AccountingCustomerParty.Party.Person.FirstName);
                setControlValue("BP_FirstSurname", Invoice.AccountingCustomerParty.Party.Person.FamilyName);
                if (Invoice.AccountingCustomerParty.Party.PartyTaxScheme != null)
                {
                    setControlValue("BP_Name", Invoice.AccountingCustomerParty.Party.PartyTaxScheme.RegistrationName);
                    setControlValue("BP_TaxIdentificationNumber", Invoice.AccountingCustomerParty.Party.PartyTaxScheme.CompanyID);
                }
                if (Invoice.AccountingCustomerParty.Party.PostalAddress != null)
                {
                    setControlValue("BP_Address", Invoice.AccountingCustomerParty.Party.PostalAddress.StreetName);
                    setControlValue("BP_BuildingNumber", Invoice.AccountingCustomerParty.Party.PostalAddress.BuildingNumber);
                    setControlValue("BP_Town", Invoice.AccountingCustomerParty.Party.PostalAddress.CityName);
                    setControlValue("BP_PostCode", Invoice.AccountingCustomerParty.Party.PostalAddress.PostalZone);
                    setControlValue("BP_Province", Invoice.AccountingCustomerParty.Party.PostalAddress.CountrySubentity);
                    setControlValue("BP_CountryCode", Invoice.AccountingCustomerParty.Party.PostalAddress.Country.IdentificationCode);
                }
                if (Invoice.AccountingCustomerParty.Party.Contact != null)
                {
                    if (Invoice.AccountingCustomerParty.Party.Contact.Telephone != null)
                    {
                        setControlValue("BP_Telephone", Invoice.AccountingCustomerParty.Party.Contact.Telephone);
                    }
                    if (Invoice.AccountingCustomerParty.Party.Contact.ElectronicMail != null)
                    {
                        setControlValue("BP_email", Invoice.AccountingCustomerParty.Party.Contact.ElectronicMail);
                    }
                }
            }
        }


        /// <summary>
        /// Método que importa los datos del tercero
        /// </summary>
        public void setSignatoryParty()
        {
            if (Invoice.Signature.SignatoryParty.PartyLegalEntity != null)
            {
                setControlValue("TH_PersonTypeCode", "J");
                setControlValue("TH_CorporateName", Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationName);
                setControlValue("TH_TaxIdentificationNumber", Invoice.Signature.SignatoryParty.PartyIdentification.ID);
                setControlValue("TH_Address", Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.StreetName);
                setControlValue("TH_BuildingNumber", Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.BuildingNumber);
                setControlValue("TH_Town", Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.CityName);
                setControlValue("TH_PostCode", Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.PostalZone);
                setControlValue("TH_Province", Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.CountrySubentity);
                setControlValue("TH_CountryCode", Invoice.Signature.SignatoryParty.PartyLegalEntity.RegistrationAddress.Country.IdentificationCode);
                if (Invoice.Signature.SignatoryParty.Contact != null)
                {
                    if (Invoice.Signature.SignatoryParty.Contact.Telephone != null)
                    {
                        setControlValue("TH_Telephone", Invoice.Signature.SignatoryParty.Contact.Telephone);
                    }
                    if (Invoice.Signature.SignatoryParty.Contact.ElectronicMail != null)
                    {
                        setControlValue("TH_email", Invoice.Signature.SignatoryParty.Contact.ElectronicMail);
                    }
                }
            }
            else
            {
                setControlValue("TH_PersonTypeCode", "F");
                setControlValue("TH_TaxIdentificationNumber", Invoice.Signature.SignatoryParty.PartyIdentification.ID);
                setControlValue("TH_Name", Invoice.Signature.SignatoryParty.Person.FirstName);
                setControlValue("TH_FirstSurname", Invoice.Signature.SignatoryParty.Person.FamilyName);
                if (Invoice.Signature.SignatoryParty.PartyTaxScheme != null)
                {
                    setControlValue("TH_Name", Invoice.Signature.SignatoryParty.PartyTaxScheme.RegistrationName);
                    setControlValue("TH_TaxIdentificationNumber", Invoice.Signature.SignatoryParty.PartyTaxScheme.CompanyID);
                }
                if (Invoice.Signature.SignatoryParty.PostalAddress != null)
                {
                    setControlValue("TH_Address", Invoice.Signature.SignatoryParty.PostalAddress.StreetName);
                    setControlValue("TH_BuildingNumber", Invoice.Signature.SignatoryParty.PostalAddress.BuildingNumber);
                    setControlValue("TH_Town", Invoice.Signature.SignatoryParty.PostalAddress.CityName);
                    setControlValue("TH_PostCode", Invoice.Signature.SignatoryParty.PostalAddress.PostalZone);
                    setControlValue("TH_Province", Invoice.Signature.SignatoryParty.PostalAddress.CountrySubentity);
                    setControlValue("TH_CountryCode", Invoice.Signature.SignatoryParty.PostalAddress.Country.IdentificationCode);
                }
                if (Invoice.Signature.SignatoryParty.Contact != null)
                {
                    if (Invoice.Signature.SignatoryParty.Contact.Telephone != null)
                    {
                        setControlValue("TH_Telephone", Invoice.Signature.SignatoryParty.Contact.Telephone);
                    }
                    if (Invoice.Signature.SignatoryParty.Contact.ElectronicMail != null)
                    {
                        setControlValue("TH_email", Invoice.Signature.SignatoryParty.Contact.ElectronicMail);
                    }
                }
            }
        }


        /// <summary>
        /// Método que importa los datos de las lineas de detalle
        /// </summary>
        public void setlineasDetalles()
        {
            document = Globals.ThisAddIn.Application.ActiveDocument;
            try
            {
                if (Invoice.InvoiceLine.Count > 0)
                {
                    DateTime dateTime = DateTime.Now;
                    foreach (InvoiceLine item in Invoice.InvoiceLine)
                    {
                        object rowBefore = document.Tables[t2].Rows.Last;
                        document.Tables[t2].Rows.Add(ref rowBefore);
                        try
                        {
                            dateTime = Convert.ToDateTime(item.Delivery.ActualDeliveryDate.ToString(), culturaOffice);
                            document.Tables[t2].Rows.Last.Previous.Cells[1].Range.Text = dateTime.ToString(culturaOffice.DateTimeFormat.ShortDatePattern);//item.Delivery.ActualDeliveryDate.ToString();
                        }
                        catch (Exception)
                        {
                        }
                        document.Tables[t2].Rows.Last.Previous.Cells[2].Range.Text = item.Item.Name;

                        document.Tables[t2].Rows.Last.Previous.Cells[3].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(item.InvoicedQuantity, culturaFactura.NumberFormat));
                        document.Tables[t2].Rows.Last.Previous.Cells[4].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(item.Price.PriceAmount.Value, culturaFactura.NumberFormat));
                        double discountRate = 0;
                        if (item.AllowanceCharge.Count == 0)
                        {
                            document.Tables[t2].Rows.Last.Previous.Cells[5].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse("0", culturaFactura.NumberFormat));
                            document.Tables[t2].Rows.Last.Previous.Cells[7].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse("0", culturaFactura.NumberFormat));
                        }
                        else
                        {
                            if (item.AllowanceCharge[0].AllowanceChargeReasonCode.Equals("02"))
                            {
                                if (double.TryParse(String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(item.AllowanceCharge[0].MultiplierFactorNumeric, culturaFactura.NumberFormat)), NumberStyles.Number, culturaOffice, out discountRate))
                                {
                                    document.Tables[t2].Rows.Last.Previous.Cells[5].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(item.AllowanceCharge[0].MultiplierFactorNumeric, culturaFactura.NumberFormat));
                                }
                                else
                                {
                                    document.Tables[t2].Rows.Last.Previous.Cells[5].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse("0", culturaFactura.NumberFormat));
                                }

                            }
                        }

                        double taxRate = 0;
                        double IRPFRate = 0;
                        if (item.TaxTotal.Count == 0)
                        {
                            document.Tables[t2].Rows.Last.Previous.Cells[6].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse("0", culturaFactura.NumberFormat));
                            document.Tables[t2].Rows.Last.Previous.Cells[7].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse("0", culturaFactura.NumberFormat));
                        }
                        for (int i = 0; i < item.TaxTotal.Count; i++)
                        {
                            if (item.TaxTotal[i].TaxSubtotal.TaxCategory.TaxScheme.TaxTypeCode.Equals("VAT"))
                            {
                                if (double.TryParse(String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(item.TaxTotal[i].TaxSubtotal.TaxCategory.Percent, culturaFactura.NumberFormat)), NumberStyles.Number, culturaOffice, out taxRate))
                                {
                                    document.Tables[t2].Rows.Last.Previous.Cells[6].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(item.TaxTotal[i].TaxSubtotal.TaxCategory.Percent, culturaFactura.NumberFormat));
                                }
                                else
                                {
                                    document.Tables[t2].Rows.Last.Previous.Cells[6].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse("0", culturaFactura.NumberFormat));
                                }
                            }
                            else if (item.TaxTotal[i].TaxSubtotal.TaxCategory.TaxScheme.TaxTypeCode.Equals("IRPF"))
                            {
                                if (double.TryParse(String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(item.TaxTotal[i].TaxSubtotal.TaxCategory.Percent, culturaFactura.NumberFormat)), NumberStyles.Number, culturaOffice, out IRPFRate))
                                {
                                    document.Tables[t2].Rows.Last.Previous.Cells[7].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(item.TaxTotal[i].TaxSubtotal.TaxCategory.Percent, culturaFactura.NumberFormat));
                                }
                                else
                                {
                                    document.Tables[t2].Rows.Last.Previous.Cells[7].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse("0", culturaFactura.NumberFormat));
                                }
                            }
                        }



                        double Quantity = Round3(double.Parse(item.InvoicedQuantity, culturaFactura.NumberFormat), 2);

                        double unitPriceWithoutTax = double.Parse(item.Price.PriceAmount.Value, culturaFactura.NumberFormat);

                        double descuento = ((Quantity * unitPriceWithoutTax) * discountRate) / 100;
                        double irpf = (((Quantity * unitPriceWithoutTax) - descuento) * IRPFRate) / 100;
                        double iva = (((Quantity * unitPriceWithoutTax) - descuento) * taxRate) / 100;

                        document.Tables[t2].Rows.Last.Previous.Cells[8].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", Round3(((Quantity * unitPriceWithoutTax) - descuento), 2));
                        document.Tables[t2].Rows.Last.Previous.Cells[9].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", Round3((((Quantity * unitPriceWithoutTax) - descuento) + (iva - irpf)), 2));
                    }
                }
            }
            catch (Exception) { }
        }

        /// <summary>
        /// Método que importa los datos de los descuentos generales
        /// </summary>
        public void setDecuentosGenerales()
        {
            if (Invoice.AllowanceCharge != null)
            {
                for (int i = 0; i < Invoice.AllowanceCharge.Count; i++)
                {
                    if (Invoice.AllowanceCharge[i].AllowanceChargeReasonCode.Equals("01"))
                    {
                        object rowBefore = document.Tables[t3].Rows.Last;
                        document.Tables[t3].Rows.Add(ref rowBefore);

                        document.Tables[t3].Rows.Last.Previous.Cells[1].Range.Text = Invoice.AllowanceCharge[i].AllowanceChargeReason.ToString();
                        document.Tables[t3].Rows.Last.Previous.Cells[2].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(Invoice.AllowanceCharge[i].MultiplierFactorNumeric, culturaFactura.NumberFormat));
                        document.Tables[t3].Rows.Last.Previous.Cells[3].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(Invoice.AllowanceCharge[i].Amount.Value, culturaFactura.NumberFormat));
                    }
                }
            }

        }

        /// <summary>
        /// Método que importa los datos de los totales
        /// </summary>
        public void setTotales()
        {
            Language language = Language.getInstance();

            try
            {
                document.Tables[t5].Rows[2].Cells[3].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(Invoice.LegalMonetaryTotal.TaxInclusiveAmount.Value, culturaFactura.NumberFormat));

                try
                {
                    document.Tables[t5].Rows[3].Cells[3].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(Invoice.LegalMonetaryTotal.AllowanceTotalAmount.Value, culturaFactura.NumberFormat));

                }
                catch (Exception)
                {
                }
                double irpfAmount = (double)0;
                for (int i = 0; i < Invoice.TaxTotal.Count; i++)
                {
                    if (Invoice.TaxTotal[i].TaxSubtotal.TaxCategory.TaxScheme.TaxTypeCode.Equals("VAT"))
                    {
                        object rowBefore = document.Tables[t5].Rows.Last;
                        document.Tables[t5].Rows.Last.Previous.Cells[2].Range.Text = language.getLabels("lbBaseAmount") + " (" + language.getLabels("lbVAT") + " " + int.Parse(double.Parse(Invoice.TaxTotal[i].TaxSubtotal.TaxCategory.Percent, culturaFactura.NumberFormat).ToString()) + ")";
                        document.Tables[t5].Rows.Last.Previous.Cells[3].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(Invoice.TaxTotal[i].TaxSubtotal.TaxableAmount.Value, culturaFactura.NumberFormat));
                        document.Tables[t5].Rows.Add(ref rowBefore);
                        rowBefore = document.Tables[t5].Rows.Last;
                        document.Tables[t5].Rows.Last.Previous.Cells[2].Range.Text = language.getLabels("lbAmount") + " (" + language.getLabels("lbVAT") + " " + int.Parse(double.Parse(Invoice.TaxTotal[i].TaxSubtotal.TaxCategory.Percent, culturaFactura.NumberFormat).ToString()) + ")";
                        document.Tables[t5].Rows.Last.Previous.Cells[3].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(Invoice.TaxTotal[i].TaxAmount.Value, culturaFactura.NumberFormat));
                        document.Tables[t5].Rows.Add(ref rowBefore);

                    }
                    else if (Invoice.TaxTotal[i].TaxSubtotal.TaxCategory.TaxScheme.TaxTypeCode.Equals("IRPF"))
                    {
                        irpfAmount += double.Parse(Invoice.TaxTotal[i].TaxAmount.Value, culturaFactura.NumberFormat);
                    }
                }
                document.Tables[t5].Rows.Last.Previous.Cells[2].Range.Text = language.getLabels("lbIRPF");
                document.Tables[t5].Rows.Last.Previous.Cells[3].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", irpfAmount);
                document.Tables[t5].Rows.Last.Cells[3].Range.Text = String.Format(culturaOffice.NumberFormat, "{0:0.00}", double.Parse(Invoice.LegalMonetaryTotal.PayableAmount.Value, culturaFactura.NumberFormat));

            }
            catch (Exception) { }
        }


        #endregion

        #region "Metodos Internos"

        /// <summary>
        /// Método que se encarga de numerar las tablas del documento
        /// </summary>
        private void enumerateTables()
        {
            try
            {

                document = Globals.ThisAddIn.Application.ActiveDocument;

                int count = document.Tables.Count;
                if (count <= 0)
                {
                    ControlMessages msg = ControlMessages.getInstance();
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorNotValidTemplate));
                }

                else
                {

                    for (int i = 2; i <= document.Tables.Count; i++)
                    {
                        try
                        {
                            string table = document.Tables[i].Rows[1].Cells[1].Range.Text.Trim(x).Trim();
                            switch (table)
                            {

                                case "2":
                                    t2 = i; break;
                                case "3":
                                    t3 = i; break;
                                case "6":
                                    t4 = i; break;
                                case "4":
                                    t5 = i; break;
                                case "1":
                                    t6 = i; break;
                                case "7":
                                    t7 = i; break;

                            }
                        }
                        catch (Exception) { }
                    }
                }
            }
            catch (Exception) { }

        }

        /// <summary>
        /// Método encargado de realizar el redondeo
        /// </summary>
        /// <param name="numero">Numero que se desea redondear</param>
        /// <param name="decimales">Numero de decimales</param>
        /// <returns>Numero redondeado</returns>
        public static double Round3(double numero, int decimales)
        {
            double multi = Math.Pow(10.0d, (double)decimales);

            if (numero < 0)
                return (-(long)((-numero * multi) + 0.5d)) / multi;
            else
                return ((long)((numero * multi) + 0.5d)) / multi;

        }

        /// <summary>
        /// Busca el ContentControl llamado tag y le asigna value a la propiedad texto
        /// </summary>
        /// <param name="tag">Nombre del ContentControl</param>
        /// <param name="value">Valor a asignarle como texto al ContentControl tag</param>
        private void setControlValue(string tag, string value)
        {

            try
            {
                foreach (Microsoft.Office.Interop.Word.ContentControl item in Globals.ThisAddIn.Application.ActiveDocument.ContentControls)
                {
                    if (!string.IsNullOrEmpty(item.Tag))
                    {
                        if (item.Tag.ToLower().Equals(tag.ToLower()))
                        {
                            if (item.Tag.Equals("TH_PersonTypeCode")
                                || item.Tag.Equals("TH_ResidenceTypeCode")
                                || item.Tag.Equals("TH_CountryCode")
                                || item.Tag.Equals("SP_PersonTypeCode")
                                || item.Tag.Equals("SP_ResidenceTypeCode")
                                || item.Tag.Equals("SP_CountryCode")
                                || item.Tag.Equals("BP_PersonTypeCode")
                                || item.Tag.Equals("BP_ResidenceTypeCode")
                                || item.Tag.Equals("BP_CountryCode")
                                || item.Tag.Equals("IH_InvoiceDocumentType")
                                || item.Tag.Equals("IH_InvoiceClass")
                                || item.Tag.Equals("CORR_ReasonCode")
                                || item.Tag.Equals("CORR_ReasonDescription"))
                            {
                                /*si lo encontramos buscamos el valor correspondiente al texto seleccionado*/
                                foreach (ContentControlListEntry entry in item.DropdownListEntries)
                                {
                                    if (!string.IsNullOrEmpty(item.Tag))
                                    {
                                        if (entry.Value.ToLower().Equals(value.ToLower()))
                                        {
                                            value = entry.Text; break;
                                        }
                                    }

                                }
                            }
                            item.Range.Text = value; break;
                        }

                    }
                }
            }
            catch (Exception) { }
        }


        /// <summary>
        /// Método que calcula el valor de moneda de cambio
        /// </summary>
        /// <returns>Un String con el valor</returns>
        private string getExchangeRate()
        {
            return String.Format(culturaOffice.NumberFormat, "{0:#,0.00}", double.Parse("1", culturaOffice.NumberFormat));
        }

        #endregion

    }
}
